package com.jilefojing.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 组合工具类
 * 
 * @author jgshun
 * 
 */
public class CombinationUtil {

	public static void main(String[] args) {
		List<List<Long>> arrs = new ArrayList<List<Long>>();
		arrs.add(Arrays.asList(new Long[] { 11L, 12L, 13L }));
		arrs.add(Arrays.asList(new Long[] { 0L }));
		arrs.add(Arrays.asList(new Long[] { 0L }));
		arrs.add(Arrays.asList(new Long[] { 0L }));
		arrs.add(Arrays.asList(new Long[] { 51L, 52L }));
		List<List<Long>> re = getCombinationResult(arrs);
		System.out.println(re);
	}

	/**
	 * arrs 里面的数组顺序组合 里面的值不重复 [[1,2],[8,9],[88,99]]--> 结果为:[[1, 8, 88], [1, 8,
	 * 99], [1, 9, 88], [1, 9, 99], [2, 8, 88], [2, 8, 99], [2, 9, 88], [2, 9,
	 * 99]]
	 * 
	 * @param arrs
	 * @return
	 */
	public static List<List<Long>> getCombinationResult(List<List<Long>> arrs) {
		if (arrs.size() < 2) {
			return arrs;
		}

		boolean isOdd = arrs.size() % 2 == 0 ? true : false;
		int rectifySize = isOdd ? arrs.size() : arrs.size() - 1;

		List<List<List<Long>>> combinations = new ArrayList<List<List<Long>>>();// 第一步取出两两组合
		for (int i = 0; i < rectifySize; i += 2) {
			combinations.add(combinationIds_1(arrs.get(i), arrs.get(i + 1)));
		}

		combinations = getCombinations(combinations);

		if (!isOdd) {
			combinations = combinationIds_5(combinations, arrs.get(arrs.size() - 1));
		}

		return combinations.get(0);
	}

	private static List<List<List<Long>>> getCombinations(List<List<List<Long>>> combinations) {
		List<List<List<Long>>> combinations2 = new ArrayList<List<List<Long>>>();// 第二步取出两两组合的组合

		if (combinations.size() < 2) {// 只有一条时
			return combinations;
		} else {
			boolean isOddComb = combinations.size() % 2 == 0 ? true : false;
			int rectifyCombSize = isOddComb ? combinations.size() : combinations.size() - 1;
			for (int i = 0; i < rectifyCombSize; i += 2) {
				combinations2.add(combinationIds_2(combinations.get(i), combinations.get(i + 1)));
			}

			if (!isOddComb) {// 奇数的情况再手动补全
				combinations2 = combinationIds_4(combinations2, combinations.get(combinations.size() - 1));
			}
			combinations2 = getCombinations(combinations2);
		}

		return combinations2;
	}

	private static List<List<List<Long>>> combinationIds_5(List<List<List<Long>>> ids_list_list_1, List<Long> ids_2) {
		List<List<List<Long>>> combinationIds_list = new ArrayList<List<List<Long>>>();
		for (List<List<Long>> ids_list_1 : ids_list_list_1) {
			List<List<Long>> combinationIds = new ArrayList<List<Long>>();
			for (List<Long> ids_1 : ids_list_1) {
				for (long id_2 : ids_2) {
					List<Long> sigleCombinationIds = new ArrayList<Long>();
					sigleCombinationIds.addAll(ids_1);
					sigleCombinationIds.add(id_2);
					combinationIds.add(sigleCombinationIds);
				}
			}
			combinationIds_list.add(combinationIds);
		}
		return combinationIds_list;
	}

	private static List<List<List<Long>>> combinationIds_4(List<List<List<Long>>> ids_list_list_1, List<List<Long>> ids_list_2) {
		List<List<List<Long>>> combinationIds = new ArrayList<List<List<Long>>>();
		for (List<List<Long>> ids_list_1 : ids_list_list_1) {
			for (List<Long> ids_2 : ids_list_2) {
				List<List<Long>> sigleCombinationIds = new ArrayList<List<Long>>();
				sigleCombinationIds.addAll(ids_list_1);
				sigleCombinationIds.add(ids_2);
				combinationIds.add(sigleCombinationIds);
			}
		}
		return combinationIds;
	}

	private static List<List<Long>> combinationIds_1(List<Long> ids_1, List<Long> ids_2) {
		List<List<Long>> combinationIds = new ArrayList<List<Long>>();
		for (long id_1 : ids_1) {
			for (long id_2 : ids_2) {
				List<Long> sigleCombinationIds = new ArrayList<Long>();
				sigleCombinationIds.add(id_1);
				sigleCombinationIds.add(id_2);
				combinationIds.add(sigleCombinationIds);
			}
		}
		return combinationIds;
	}

	private static List<List<Long>> combinationIds_3(List<List<Long>> ids_list_1, List<Long> ids_2) {
		List<List<Long>> combinationIds = new ArrayList<List<Long>>();
		for (List<Long> ids_1 : ids_list_1) {
			for (long id_2 : ids_2) {
				List<Long> sigleCombinationIds = new ArrayList<Long>();
				sigleCombinationIds.addAll(ids_1);
				sigleCombinationIds.add(id_2);
				combinationIds.add(sigleCombinationIds);
			}
		}
		return combinationIds;
	}

	private static List<List<Long>> combinationIds_2(List<List<Long>> ids_list_1, List<List<Long>> ids_list_2) {
		List<List<Long>> combinationIds = new ArrayList<List<Long>>();
		for (List<Long> ids_1 : ids_list_1) {
			for (List<Long> ids_2 : ids_list_2) {
				List<Long> sigleCombinationIds = new ArrayList<Long>();
				sigleCombinationIds.addAll(ids_1);
				sigleCombinationIds.addAll(ids_2);
				combinationIds.add(sigleCombinationIds);
			}
		}
		return combinationIds;
	}

}
